package ru.niir.goodfil.db;

import static ru.niir.goodfil.utils.Utils.s;

import javax.persistence.*;
import java.io.Serializable;

/**
 * Настройки системы (одна опция)
 */
@Entity
@Table(name = "`Settings`")
public class Setting implements Serializable
{
    /**
     * Наименование опции
     */
    @Id
    @Column(name = "`Key`", nullable = false, length = 200)
    private String key;

    /**
     * Значение опции
     */
    @Column(name = "`Value`", nullable = false, length = 300)
    private String value;

    /**
     * Комментарий (название для оператора)
     */
    @Column(name = "`Comment`", nullable = false, length = 500)
    private String comment = "";

    /**
     * Конструктор
     */
    public Setting()
    {}

    /**
     * Конструктор
     * @param key наименование опции
     * @param value значение опции
     */
    public Setting(String key, String value)
    {
        this.key = s(key);
        this.value = s(value);
    }

    /**
     * Конструктор
     * @param key наименование опции
     * @param value значение опции
     * @param comment комментарий
     */
    public Setting(String key, String value, String comment)
    {
        this.key = s(key);
        this.value = s(value);
        this.comment = s(comment);
    }

    /**
     * Получить значение опции в виде объекта boolean.
     * Если привести строковое значение опции к данному типу невозможно, выбрасывается NullPointerException.
     */
    public boolean getValueAsBoolean()
    {
        if (value.equals("1") || value.equals("true")) return true;
        else if (value.equals("0") || value.equals("false")) return false;

        throw new NullPointerException("Setting value " + value + " cannot be cast to Boolean");
    }


    /**
     * Получить значение опции в виде объекта integer.
     * Если привести строковое значение опции к данному типу невозможно, выбрасывается NullPointerException.
     */
    public int getValueAsInteger()
    {
        try
        {
            return Integer.parseInt(value);
        }
        catch (NumberFormatException nfe)
        {
            throw new NullPointerException("Setting value " + value + " cannot be cast to Integer");
        }
    }

    /**
     * Получить значение опции в виде объекта float.
     * Если привести строковое значение опции к данному типу невозможно, выбрасывается NullPointerException.
     */
    public float getValueAsFloat()
    {
        try
        {
            return Integer.parseInt(value);
        }
        catch (NumberFormatException nfe)
        {
            throw new NullPointerException("Setting value " + value + " cannot be cast to Float");
        }
    }

    @Override
    public String toString()
    {
        return "Setting{" +
               "key='" + key + '\'' +
               ", value='" + value + '\'' +
               ", comment='" + comment + '\'' +
               '}';
    }

    public void setKey(String key)
    {
        this.key = s(key);
    }

    /**
     * Получить наименование опции
     */
    public String getKey()
    {
        return key;
    }

    /**
     * Получить значение опции
     */
    public String getValue()
    {
        return value;
    }

    /**
     * Установить значение опции (не null)
     */
    public void setValue(String value)
    {
        this.value = s(value);
    }

    /**
     * Получить комментарий к данной опции
     */
    public String getComment()
    {
        return comment;
    }

    /**
     * Установить комментарий к данной опции (не null)
     */
    public void setComment(String comment)
    {
        this.comment = s(comment);
    }

    /**
     * Возвращает true, если данная настройка - системная, т.е. ее наименование начинается с точки
     * @return true, если данная настройка - системная, т.е. ее наименование начинается с точки
     */
    public boolean getIsHidden()
    {
        return key.charAt(0) == '.';
    }
}
